home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Applications / Tcl-Tk 8.0 / Pre-installed version / tk8.0 / mac / tkMacSubwindows.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-08-15  |  29.8 KB  |  1,221 lines  |  [TEXT/CWIE]

  1. /* 
  2.  * tkMacSubwindows.c --
  3.  *
  4.  *    Implements subwindows for the macintosh version of Tk.
  5.  *
  6.  * Copyright (c) 1995-1997 Sun Microsystems, Inc.
  7.  *
  8.  * See the file "license.terms" for information on usage and redistribution
  9.  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  10.  *
  11.  * SCCS: @(#) tkMacSubwindows.c 1.78 97/08/06 21:34:46
  12.  */
  13.  
  14. #include "tkInt.h"
  15. #include "X.h"
  16. #include "Xlib.h"
  17. #include <stdio.h>
  18.  
  19. #include <Windows.h>
  20. #include <QDOffscreen.h>
  21. #include "tkMacInt.h"
  22.  
  23. /*
  24.  * Temporary region that can be reused.
  25.  */
  26. static RgnHandle tmpRgn = NULL;
  27.  
  28. static void UpdateOffsets _ANSI_ARGS_((TkWindow *winPtr, int deltaX, int deltaY));
  29.  
  30. void MacMoveWindow _ANSI_ARGS_((WindowRef window, int x, int y));
  31.  
  32. /*
  33.  *----------------------------------------------------------------------
  34.  *
  35.  * XDestroyWindow --
  36.  *
  37.  *    Dealocates the given X Window.
  38.  *
  39.  * Results:
  40.  *    The window id is returned.
  41.  *
  42.  * Side effects:
  43.  *    None.
  44.  *
  45.  *----------------------------------------------------------------------
  46.  */
  47.  
  48. void 
  49. XDestroyWindow(
  50.     Display* display,        /* Display. */
  51.     Window window)        /* Window. */
  52. {
  53.     MacDrawable *macWin = (MacDrawable *) window;
  54.     GWorldPtr destPort;
  55.  
  56.     /*
  57.      * Remove any dangling pointers that may exist if
  58.      * the window we are deleting is being tracked by
  59.      * the grab or focus code.
  60.      */
  61.     if (tkMacFocusWin == (Tk_Window) macWin->winPtr) {
  62.     tkMacFocusWin = NULL;
  63.     }
  64.     TkPointerDeadWindow(macWin->winPtr);
  65.     macWin->toplevel->referenceCount--;
  66.     
  67.     
  68.     if (Tk_IsTopLevel(macWin->winPtr)) {
  69.     DisposeRgn(macWin->clipRgn);
  70.     DisposeRgn(macWin->aboveClipRgn);
  71.     
  72.     /*
  73.      * Delete the Mac window and remove it from the windowTable.
  74.      * The window could be NULL if the window was never mapped.
  75.      * However, we don't do this for embedded windows, they don't
  76.      * go in the window list, and they do not own their portPtr's.
  77.      */
  78.      
  79.     if (!(Tk_IsEmbedded(macWin->winPtr))) {
  80.             destPort = TkMacGetDrawablePort(window);
  81.         if (destPort != NULL) {
  82.             TkMacWindowList *listPtr, *prevPtr;
  83.         
  84.             TkMacUnregisterMacWindow(destPort);
  85.             DisposeWindow((WindowRef) destPort);
  86.         
  87.             for (listPtr = tkMacWindowListPtr, prevPtr = NULL;
  88.                     tkMacWindowListPtr != NULL;
  89.                     prevPtr = listPtr, listPtr = listPtr->nextPtr) {
  90.                 if (listPtr->winPtr == macWin->winPtr) {
  91.                     if (prevPtr == NULL) {
  92.                         tkMacWindowListPtr = listPtr->nextPtr;
  93.                     } else {
  94.                         prevPtr->nextPtr = listPtr->nextPtr;
  95.                     }
  96.                     ckfree((char *) listPtr);
  97.                     break;
  98.                 }
  99.             }
  100.         }
  101.     }
  102.     
  103.     macWin->portPtr = NULL;
  104.     
  105.     /*
  106.      * Delay deletion of a toplevel data structure untill all
  107.      * children have been deleted.
  108.      */
  109.     if (macWin->toplevel->referenceCount == 0) {
  110.         ckfree((char *) macWin->toplevel);
  111.     }
  112.     } else {
  113.         destPort = TkMacGetDrawablePort(window);
  114.     if (destPort != NULL) {
  115.         SetGWorld(destPort, NULL);
  116.         TkMacInvalidateWindow(macWin, TK_PARENT_WINDOW);
  117.     }
  118.     if (macWin->winPtr->parentPtr != NULL) {
  119.         TkMacInvalClipRgns(macWin->winPtr->parentPtr);
  120.     }
  121.     DisposeRgn(macWin->clipRgn);
  122.     DisposeRgn(macWin->aboveClipRgn);
  123.     
  124.     if (macWin->toplevel->referenceCount == 0) {
  125.         ckfree((char *) macWin->toplevel);
  126.     }
  127.     ckfree((char *) macWin);
  128.     }
  129. }
  130.  
  131. /*
  132.  *----------------------------------------------------------------------
  133.  *
  134.  * XMapWindow --
  135.  *
  136.  *    Map the given X Window to the screen.  See X window documentation 
  137.  *  for more details.
  138.  *
  139.  * Results:
  140.  *    None.
  141.  *
  142.  * Side effects:
  143.  *    The subwindow or toplevel may appear on the screen.
  144.  *
  145.  *----------------------------------------------------------------------
  146.  */
  147.  
  148. void 
  149. XMapWindow(
  150.     Display* display,        /* Display. */
  151.     Window window)        /* Window. */
  152. {
  153.     MacDrawable *macWin = (MacDrawable *) window;
  154.     XEvent event;
  155.     GWorldPtr destPort;
  156.  
  157.     /*
  158.      * Under certain situations it's possible for this function to be
  159.      * called before the toplevel window it's associated with has actually
  160.      * been mapped.  In that case we need to create the real Macintosh
  161.      * window now as this function as well as other X functions assume that
  162.      * the portPtr is valid.
  163.      */
  164.     if (!TkMacHostToplevelExists(macWin->toplevel->winPtr)) {
  165.     TkMacMakeRealWindowExist(macWin->toplevel->winPtr);
  166.     }
  167.     destPort = TkMacGetDrawablePort(window);
  168.  
  169.     display->request++;
  170.     macWin->winPtr->flags |= TK_MAPPED;
  171.     if (Tk_IsTopLevel(macWin->winPtr)) {
  172.     if (!Tk_IsEmbedded(macWin->winPtr)) {
  173.         ShowWindow((WindowRef) destPort);
  174.     }
  175.  
  176.     /* 
  177.      * We only need to send the MapNotify event
  178.      * for toplevel windows.
  179.      */
  180.     event.xany.serial = display->request;
  181.     event.xany.send_event = False;
  182.     event.xany.display = display;
  183.     
  184.     event.xmap.window = window;
  185.     event.xmap.type = MapNotify;
  186.     event.xmap.event = window;
  187.     event.xmap.override_redirect = macWin->winPtr->atts.override_redirect;
  188.     Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
  189.     } else {
  190.     TkMacInvalClipRgns(macWin->winPtr->parentPtr);
  191.     }
  192.  
  193.     /* 
  194.      * Generate damage for that area of the window 
  195.      */
  196.     SetGWorld(destPort, NULL);
  197.     TkMacUpdateClipRgn(macWin->winPtr);
  198.     TkMacInvalidateWindow(macWin, TK_PARENT_WINDOW);
  199. }
  200.  
  201. /*
  202.  *----------------------------------------------------------------------
  203.  *
  204.  * XUnmapWindow --
  205.  *
  206.  *    Unmap the given X Window to the screen.  See X window
  207.  *    documentation for more details.
  208.  *
  209.  * Results:
  210.  *    None.
  211.  *
  212.  * Side effects:
  213.  *    The subwindow or toplevel may be removed from the screen.
  214.  *
  215.  *----------------------------------------------------------------------
  216.  */
  217.  
  218. void 
  219. XUnmapWindow(
  220.     Display* display,        /* Display. */
  221.     Window window)        /* Window. */
  222. {
  223.     MacDrawable *macWin = (MacDrawable *) window;
  224.     XEvent event;
  225.     GWorldPtr destPort;
  226.  
  227.     destPort = TkMacGetDrawablePort(window);
  228.  
  229.     display->request++;
  230.     macWin->winPtr->flags &= ~TK_MAPPED;
  231.     if (Tk_IsTopLevel(macWin->winPtr)) {
  232.     if (!Tk_IsEmbedded(macWin->winPtr)) {
  233.         HideWindow((WindowRef) destPort);
  234.     }
  235.  
  236.     /* 
  237.      * We only need to send the UnmapNotify event
  238.      * for toplevel windows.
  239.      */
  240.     event.xany.serial = display->request;
  241.     event.xany.send_event = False;
  242.     event.xany.display = display;
  243.     
  244.     event.xunmap.type = UnmapNotify;
  245.     event.xunmap.window = window;
  246.     event.xunmap.event = window;
  247.     event.xunmap.from_configure = false;
  248.     Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
  249.     } else {
  250.     /* 
  251.      * Generate damage for that area of the window.
  252.      */
  253.     SetGWorld(destPort, NULL);
  254.     TkMacInvalidateWindow(macWin, TK_PARENT_WINDOW); /* TODO: may not be valid */
  255.     TkMacInvalClipRgns(macWin->winPtr->parentPtr);
  256.     }
  257. }
  258.  
  259. /*
  260.  *----------------------------------------------------------------------
  261.  *
  262.  * XResizeWindow --
  263.  *
  264.  *    Resize a given X window.  See X windows documentation for
  265.  *    further details.
  266.  *
  267.  * Results:
  268.  *    None.
  269.  *
  270.  * Side effects:
  271.  *    None.
  272.  *
  273.  *----------------------------------------------------------------------
  274.  */
  275.  
  276. void 
  277. XResizeWindow(
  278.     Display* display,        /* Display. */
  279.     Window window,         /* Window. */
  280.     unsigned int width,
  281.     unsigned int height)
  282. {
  283.     MacDrawable *macWin = (MacDrawable *) window;
  284.     GWorldPtr destPort;
  285.  
  286.     destPort = TkMacGetDrawablePort(window);
  287.  
  288.     display->request++;
  289.     SetPort((GrafPtr) destPort);
  290.     if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
  291.     /* 
  292.      * NOTE: we are not adding the new space to the update
  293.      * region.  It is currently assumed that Tk will need
  294.      * to completely redraw anway.
  295.      */
  296.     SizeWindow((WindowRef) destPort,
  297.         (short) width, (short) height, false);
  298.     TkMacInvalidateWindow(macWin, TK_WINDOW_ONLY);
  299.     TkMacInvalClipRgns(macWin->winPtr);
  300.     } else {
  301.     /* TODO: update all xOff & yOffs */
  302.     int deltaX, deltaY, parentBorderwidth;
  303.     MacDrawable *macParent = macWin->winPtr->parentPtr->privatePtr;
  304.  
  305.         /*
  306.          * Find the Parent window -
  307.          *    For an embedded window this will be its container.
  308.          */
  309.          
  310.     if (Tk_IsEmbedded(macWin->winPtr)) {
  311.         TkWindow *contWinPtr;
  312.         
  313.         contWinPtr = TkpGetOtherWindow(macWin->winPtr);
  314.         if (contWinPtr == NULL) {
  315.                 panic("XMoveResizeWindow could not find container");
  316.         }
  317.         macParent = contWinPtr->privatePtr;
  318.         
  319.         /*
  320.          * NOTE: Here we should handle out of process embedding.
  321.          */
  322.     
  323.     } else {
  324.         macParent = macWin->winPtr->parentPtr->privatePtr;   
  325.         if (macParent == NULL) {
  326.             return; /* TODO: Probably should be a panic */
  327.         }
  328.     }
  329.     
  330.     TkMacInvalClipRgns(macParent->winPtr);
  331.     TkMacInvalidateWindow(macWin, TK_PARENT_WINDOW);
  332.  
  333.     deltaX = - macWin->xOff;
  334.     deltaY = - macWin->yOff;
  335.  
  336.         /*
  337.      * If macWin->winPtr is an embedded window, don't offset by its
  338.      *  parent's borderwidth...
  339.      */
  340.      
  341.     if (!Tk_IsEmbedded(macWin->winPtr)) {
  342.         parentBorderwidth = macWin->winPtr->parentPtr->changes.border_width;
  343.     } else {
  344.         parentBorderwidth = 0;
  345.     }
  346.     deltaX += macParent->xOff + parentBorderwidth +
  347.         macWin->winPtr->changes.x;
  348.     deltaY += macParent->yOff + parentBorderwidth +
  349.         macWin->winPtr->changes.y;
  350.  
  351.     UpdateOffsets(macWin->winPtr, deltaX, deltaY);
  352.     }
  353. }
  354.  
  355. /*
  356.  *----------------------------------------------------------------------
  357.  *
  358.  * XMoveResizeWindow --
  359.  *
  360.  *    Move or resize a given X window.  See X windows documentation
  361.  *    for further details.
  362.  *
  363.  * Results:
  364.  *    None.
  365.  *
  366.  * Side effects:
  367.  *    None.
  368.  *
  369.  *----------------------------------------------------------------------
  370.  */
  371.  
  372. void 
  373. XMoveResizeWindow(
  374.     Display* display,        /* Display. */
  375.     Window window,         /* Window. */
  376.     int x, int y,
  377.     unsigned int width,
  378.     unsigned int height)
  379. {    
  380.     MacDrawable *macWin = (MacDrawable *) window;
  381.     GWorldPtr destPort;
  382.  
  383.     destPort = TkMacGetDrawablePort(window);
  384.  
  385.     SetPort((GrafPtr) destPort);
  386.     if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {    
  387.     /* 
  388.      * NOTE: we are not adding the new space to the update
  389.      * region.  It is currently assumed that Tk will need
  390.      * to completely redraw anway.
  391.      */
  392.     
  393.     SizeWindow((WindowRef) destPort,
  394.         (short) width, (short) height, false);
  395.     MacMoveWindow((WindowRef) destPort, x, y);
  396.     
  397.     /* TODO: is the following right? */
  398.     TkMacInvalidateWindow(macWin, TK_WINDOW_ONLY);
  399.     TkMacInvalClipRgns(macWin->winPtr);
  400.     } else {
  401.     int deltaX, deltaY, parentBorderwidth;
  402.     Rect bounds;
  403.     MacDrawable *macParent;
  404.     
  405.         /*
  406.          * Find the Parent window -
  407.          *    For an embedded window this will be its container.
  408.          */
  409.          
  410.     if (Tk_IsEmbedded(macWin->winPtr)) {
  411.         TkWindow *contWinPtr;
  412.         
  413.         contWinPtr = TkpGetOtherWindow(macWin->winPtr);
  414.         if (contWinPtr == NULL) {
  415.                 panic("XMoveResizeWindow could not find container");
  416.         }
  417.         macParent = contWinPtr->privatePtr;
  418.         
  419.         /*
  420.          * NOTE: Here we should handle out of process embedding.
  421.          */
  422.     
  423.         
  424.     } else {
  425.         macParent = macWin->winPtr->parentPtr->privatePtr;   
  426.         if (macParent == NULL) {
  427.             return; /* TODO: Probably should be a panic */
  428.         }
  429.     }
  430.             
  431.     TkMacInvalClipRgns(macParent->winPtr);
  432.     TkMacInvalidateWindow(macWin, TK_PARENT_WINDOW);
  433.  
  434.     deltaX = - macWin->xOff;
  435.     deltaY = - macWin->yOff;
  436.     
  437.         /*
  438.      * If macWin->winPtr is an embedded window, don't offset by its
  439.      *  parent's borderwidth...
  440.      */
  441.      
  442.     if (!Tk_IsEmbedded(macWin->winPtr)) {
  443.         parentBorderwidth = macWin->winPtr->parentPtr->changes.border_width;
  444.     } else {
  445.         parentBorderwidth = 0;
  446.     }
  447.     deltaX += macParent->xOff + parentBorderwidth +
  448.         macWin->winPtr->changes.x;
  449.     deltaY += macParent->yOff + parentBorderwidth +
  450.         macWin->winPtr->changes.y;
  451.         
  452.     UpdateOffsets(macWin->winPtr, deltaX, deltaY);
  453.     TkMacWinBounds(macWin->winPtr, &bounds);
  454.     InvalRect(&bounds);
  455.     }
  456. }
  457.  
  458. /*
  459.  *----------------------------------------------------------------------
  460.  *
  461.  * XMoveWindow --
  462.  *
  463.  *    Move a given X window.  See X windows documentation for further
  464.  *  details.
  465.  *
  466.  * Results:
  467.  *    None.
  468.  *
  469.  * Side effects:
  470.  *    None.
  471.  *
  472.  *----------------------------------------------------------------------
  473.  */
  474.  
  475. void 
  476. XMoveWindow(
  477.     Display* display,        /* Display. */
  478.     Window window,        /* Window. */
  479.     int x,
  480.     int y)
  481. {
  482.     MacDrawable *macWin = (MacDrawable *) window;
  483.     GWorldPtr destPort;
  484.  
  485.     destPort = TkMacGetDrawablePort(window);
  486.  
  487.     SetPort((GrafPtr) destPort);
  488.     if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
  489.     /* 
  490.      * NOTE: we are not adding the new space to the update
  491.      * region.  It is currently assumed that Tk will need
  492.      * to completely redraw anway.
  493.      */
  494.     MacMoveWindow((WindowRef) destPort, x, y);
  495.  
  496.     /* TODO: is the following right? */
  497.     TkMacInvalidateWindow(macWin, TK_WINDOW_ONLY);
  498.     TkMacInvalClipRgns(macWin->winPtr);
  499.     } else {
  500.     int deltaX, deltaY, parentBorderwidth;
  501.     Rect bounds;
  502.     MacDrawable *macParent;
  503.     
  504.         /*
  505.          * Find the Parent window -
  506.          * For an embedded window this will be its container.
  507.          */
  508.          
  509.     if (Tk_IsEmbedded(macWin->winPtr)) {
  510.         TkWindow *contWinPtr;
  511.         
  512.         contWinPtr = TkpGetOtherWindow(macWin->winPtr);
  513.         if (contWinPtr == NULL) {
  514.                 panic("XMoveWindow could not find container");
  515.         }
  516.         macParent = contWinPtr->privatePtr;
  517.         
  518.         /*
  519.          * NOTE: Here we should handle out of process embedding.
  520.          */
  521.             
  522.     } else {
  523.         macParent = macWin->winPtr->parentPtr->privatePtr;   
  524.         if (macParent == NULL) {
  525.             return; /* TODO: Probably should be a panic */
  526.         }
  527.     }
  528.  
  529.     TkMacInvalClipRgns(macParent->winPtr);
  530.     TkMacInvalidateWindow(macWin, TK_PARENT_WINDOW);
  531.  
  532.     deltaX = - macWin->xOff;
  533.     deltaY = - macWin->yOff;
  534.     
  535.         /*
  536.      * If macWin->winPtr is an embedded window, don't offset by its
  537.      *  parent's borderwidth...
  538.      */
  539.      
  540.     if (!Tk_IsEmbedded(macWin->winPtr)) {
  541.         parentBorderwidth = macWin->winPtr->parentPtr->changes.border_width;
  542.     } else {
  543.         parentBorderwidth = 0;
  544.     }
  545.     deltaX += macParent->xOff + parentBorderwidth +
  546.         macWin->winPtr->changes.x;
  547.     deltaY += macParent->yOff + parentBorderwidth +
  548.         macWin->winPtr->changes.y;
  549.         
  550.     UpdateOffsets(macWin->winPtr, deltaX, deltaY);
  551.     TkMacWinBounds(macWin->winPtr, &bounds);
  552.     InvalRect(&bounds);
  553.     }
  554. }
  555.  
  556. /*
  557.  *----------------------------------------------------------------------
  558.  *
  559.  * XRaiseWindow --
  560.  *
  561.  *    Change the stacking order of a window.
  562.  *
  563.  * Results:
  564.  *    None.
  565.  *
  566.  * Side effects:
  567.  *    Changes the stacking order of the specified window.
  568.  *
  569.  *----------------------------------------------------------------------
  570.  */
  571.  
  572. void 
  573. XRaiseWindow(
  574.     Display* display,        /* Display. */
  575.     Window window)        /* Window. */
  576. {
  577.     MacDrawable *macWin = (MacDrawable *) window;
  578.     
  579.     display->request++;
  580.     if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
  581.     TkWmRestackToplevel(macWin->winPtr, Above, NULL);
  582.     } else {
  583.         /* TODO: this should generate damage */
  584.     }
  585. }
  586.  
  587. /*
  588.  *----------------------------------------------------------------------
  589.  *
  590.  * XConfigureWindow --
  591.  *
  592.  *    Change the size, position, stacking, or border of the specified
  593.  *    window.
  594.  *
  595.  * Results:
  596.  *    None.
  597.  *
  598.  * Side effects:
  599.  *    Changes the attributes of the specified window.  Note that we
  600.  *    ignore the passed in values and use the values stored in the
  601.  *    TkWindow data structure.
  602.  *
  603.  *----------------------------------------------------------------------
  604.  */
  605.  
  606. void
  607. XConfigureWindow(
  608.     Display* display,        /* Display. */
  609.     Window w,            /* Window. */
  610.     unsigned int value_mask,
  611.     XWindowChanges* values)
  612. {
  613.     MacDrawable *macWin = (MacDrawable *) w;
  614.     TkWindow *winPtr = macWin->winPtr;
  615.  
  616.     display->request++;
  617.  
  618.     /*
  619.      * Change the shape and/or position of the window.
  620.      */
  621.  
  622.     if (value_mask & (CWX|CWY|CWWidth|CWHeight)) {
  623.     XMoveResizeWindow(display, w, winPtr->changes.x, winPtr->changes.y,
  624.         winPtr->changes.width, winPtr->changes.height);
  625.     }
  626.  
  627.     /*
  628.      * Change the stacking order of the window.  Tk actuall keeps all
  629.      * the information we need for stacking order.  All we need to do
  630.      * is make sure the clipping regions get updated and generate damage
  631.      * that will ensure things get drawn correctly.
  632.      */
  633.  
  634.     if (value_mask & CWStackMode) {
  635.     Rect bounds;
  636.     GWorldPtr destPort;
  637.     
  638.     destPort = TkMacGetDrawablePort(w);
  639.     if (destPort != NULL) {
  640.         SetPort((GrafPtr) destPort);
  641.         TkMacInvalClipRgns(winPtr->parentPtr);
  642.         TkMacWinBounds(winPtr, &bounds);
  643.         InvalRect(&bounds);
  644.     }
  645.     } 
  646.  
  647.     /* TkGenWMMoveRequestEvent(macWin->winPtr, 
  648.         macWin->winPtr->changes.x, macWin->winPtr->changes.y); */
  649. }
  650.  
  651. /*
  652.  *----------------------------------------------------------------------
  653.  *
  654.  *  TkMacUpdateClipRgn --
  655.  *
  656.  *    This function updates the cliping regions for a given window
  657.  *    and all of its children.  Once updated the TK_CLIP_INVALID flag
  658.  *    in the subwindow data structure is unset.  The TK_CLIP_INVALID 
  659.  *    flag should always be unset before any drawing is attempted.
  660.  *
  661.  * Results:
  662.  *    None.
  663.  *
  664.  * Side effects:
  665.  *    The clip regions for the window and its children are updated.
  666.  *
  667.  *----------------------------------------------------------------------
  668.  */
  669.  
  670. void
  671. TkMacUpdateClipRgn(
  672.     TkWindow *winPtr)
  673. {
  674.     RgnHandle rgn;
  675.     int x, y;
  676.     TkWindow *win2Ptr;
  677.  
  678.     if (winPtr == NULL) {
  679.     return;
  680.     }
  681.     
  682.     if (winPtr->privatePtr->flags & TK_CLIP_INVALID) {
  683.     rgn = winPtr->privatePtr->aboveClipRgn;
  684.     if (tmpRgn == NULL) {
  685.         tmpRgn = NewRgn();
  686.     }
  687.     
  688.     /* 
  689.      * Start with a region defined by the window bounds.  
  690.      */
  691.  
  692.         x = winPtr->privatePtr->xOff;
  693.         y = winPtr->privatePtr->yOff;
  694.         SetRectRgn(rgn, (short) x, (short) y,
  695.         (short) (winPtr->changes.width  + x), 
  696.         (short) (winPtr->changes.height + y));
  697.         
  698.     /* 
  699.      * Clip away the area of any windows that may obscure this
  700.      * window.  
  701.      * For a non-toplevel window, first, clip to the parents visable
  702.      * clip region.
  703.      * Second, clip away any siblings that are higher in the
  704.      * stacking order.
  705.      * For an embedded toplevel, just clip to the container's visible
  706.      * clip region.  Remember, we only allow one contained window 
  707.      * in a frame, and don't support any other widgets in the frame either.
  708.      * This is not currently enforced, however.
  709.      */
  710.     
  711.     if (!Tk_IsTopLevel(winPtr)) { 
  712.         TkMacUpdateClipRgn(winPtr->parentPtr);
  713.         SectRgn(rgn, 
  714.             winPtr->parentPtr->privatePtr->aboveClipRgn, rgn);
  715.                 
  716.         win2Ptr = winPtr->nextPtr;
  717.         while (win2Ptr != NULL) {
  718.         if (Tk_IsTopLevel(win2Ptr) || !Tk_IsMapped(win2Ptr)) {
  719.             win2Ptr = win2Ptr->nextPtr;
  720.             continue;
  721.         }
  722.         x = win2Ptr->privatePtr->xOff;
  723.         y = win2Ptr->privatePtr->yOff;
  724.         SetRectRgn(tmpRgn, (short) x, (short) y,
  725.             (short) (win2Ptr->changes.width  + x), 
  726.             (short) (win2Ptr->changes.height + y));
  727.         DiffRgn(rgn, tmpRgn, rgn);
  728.                               
  729.         win2Ptr = win2Ptr->nextPtr;
  730.         }
  731.     } else if (Tk_IsEmbedded(winPtr)) {
  732.             TkWindow *contWinPtr;
  733.         
  734.         contWinPtr = TkpGetOtherWindow(winPtr);
  735.              
  736.             if (contWinPtr != NULL) {
  737.              TkMacUpdateClipRgn(contWinPtr);
  738.             SectRgn(rgn, 
  739.                 contWinPtr->privatePtr->aboveClipRgn, rgn);
  740.            }
  741.         
  742.         /*
  743.          * NOTE: Here we should handle out of process embedding.
  744.          */
  745.             
  746.     }
  747.     
  748.     /* 
  749.      * The final clip region is the aboveClip region (or visable
  750.      * region) minus all the children of this window.
  751.      * Alternatively, if the window is a container, we must also 
  752.      * subtract the region of the embedded window.
  753.      */
  754.      
  755.     rgn = winPtr->privatePtr->clipRgn;
  756.     CopyRgn(winPtr->privatePtr->aboveClipRgn, rgn);
  757.         
  758.     win2Ptr = winPtr->childList;
  759.     while (win2Ptr != NULL) {
  760.         if (Tk_IsTopLevel(win2Ptr) || !Tk_IsMapped(win2Ptr)) {
  761.         win2Ptr = win2Ptr->nextPtr;
  762.         continue;
  763.         }
  764.         x = win2Ptr->privatePtr->xOff;
  765.         y = win2Ptr->privatePtr->yOff;
  766.         SetRectRgn(tmpRgn, (short) x, (short) y,
  767.             (short) (win2Ptr->changes.width  + x), 
  768.             (short) (win2Ptr->changes.height + y));
  769.         DiffRgn(rgn, tmpRgn, rgn);
  770.                               
  771.         win2Ptr = win2Ptr->nextPtr;
  772.     }
  773.     
  774.     if (Tk_IsContainer(winPtr)) {
  775.         win2Ptr = TkpGetOtherWindow(winPtr);
  776.         if (win2Ptr != NULL) {
  777.         if (Tk_IsMapped(win2Ptr)) {
  778.             x = win2Ptr->privatePtr->xOff;
  779.             y = win2Ptr->privatePtr->yOff;
  780.             SetRectRgn(tmpRgn, (short) x, (short) y,
  781.                 (short) (win2Ptr->changes.width  + x), 
  782.                 (short) (win2Ptr->changes.height + y));
  783.             DiffRgn(rgn, tmpRgn, rgn);
  784.         }
  785.         } 
  786.         
  787.         /*
  788.          * NOTE: Here we should handle out of process embedding.
  789.          */
  790.             
  791.     }
  792.         
  793.     winPtr->privatePtr->flags &= ~TK_CLIP_INVALID;
  794.     }
  795. }
  796.  
  797. /*
  798.  *----------------------------------------------------------------------
  799.  *
  800.  * TkMacVisableClipRgn --
  801.  *
  802.  *    This function returnd the Macintosh cliping region for the 
  803.  *    given window.  A NULL Rgn means the window is not visable.
  804.  *
  805.  * Results:
  806.  *    The region.
  807.  *
  808.  * Side effects:
  809.  *    None.
  810.  *
  811.  *----------------------------------------------------------------------
  812.  */
  813.  
  814. RgnHandle
  815. TkMacVisableClipRgn(
  816.     TkWindow *winPtr)
  817. {
  818.     if (winPtr->privatePtr->flags & TK_CLIP_INVALID) {
  819.     TkMacUpdateClipRgn(winPtr);
  820.     }
  821.  
  822.     return winPtr->privatePtr->clipRgn;
  823. }
  824.  
  825. /*
  826.  *----------------------------------------------------------------------
  827.  *
  828.  * TkMacInvalidateWindow --
  829.  *
  830.  *    This function makes the window as invalid will generate damage
  831.  *    for the window.
  832.  *
  833.  * Results:
  834.  *    None.
  835.  *
  836.  * Side effects:
  837.  *    Damage is created.
  838.  *
  839.  *----------------------------------------------------------------------
  840.  */
  841.  
  842. void
  843. TkMacInvalidateWindow(
  844.     MacDrawable *macWin,        /* Make window that's causing damage. */
  845.     int flag)            /* Should be TK_WINDOW_ONLY or
  846.                  * TK_PARENT_WINDOW */
  847. {
  848.     
  849.     if (flag == TK_WINDOW_ONLY) {
  850.     InvalRgn(macWin->clipRgn);
  851.     } else {
  852.     if (!EmptyRgn(macWin->aboveClipRgn)) {
  853.         InvalRgn(macWin->aboveClipRgn);
  854.     }
  855.     }
  856. }
  857.  
  858. /*
  859.  *----------------------------------------------------------------------
  860.  *
  861.  * TkMacGetDrawablePort --
  862.  *
  863.  *    This function returns the Graphics Port for a given X drawable.
  864.  *
  865.  * Results:
  866.  *    A GWorld pointer.  Either an off screen pixmap or a Window.
  867.  *
  868.  * Side effects:
  869.  *    None.
  870.  *
  871.  *----------------------------------------------------------------------
  872.  */
  873.  
  874. GWorldPtr
  875. TkMacGetDrawablePort(
  876.     Drawable drawable)
  877. {
  878.     MacDrawable *macWin = (MacDrawable *) drawable;
  879.     
  880.     if (macWin == NULL) {
  881.         return NULL;
  882.     }
  883.     
  884.     /*
  885.      * This is NULL for off-screen pixmaps.  Then the portPtr
  886.      * always points to the off-screen port, and we don't
  887.      * have to worry about containment
  888.      */
  889.      
  890.     if (macWin->clipRgn == NULL) {
  891.     return macWin->portPtr;
  892.     }
  893.     
  894.     /*
  895.      * If the Drawable is in an embedded window, use the Port of its container.
  896.      *  
  897.      * TRICKY POINT: we can have cases when a toplevel is being destroyed
  898.      * where the winPtr for the toplevel has been freed, but the children 
  899.      * are not all the way destroyed.  The children will call this function
  900.      * as they are being destroyed, but Tk_IsEmbedded will return garbage.
  901.      * So we check the copy of the TK_EMBEDDED flag we put into the 
  902.      * toplevel's macWin flags.
  903.      */
  904.     
  905.     if (!(macWin->toplevel->flags & TK_EMBEDDED)) {
  906.         return macWin->toplevel->portPtr;
  907.     } else {
  908.         TkWindow *contWinPtr;
  909.  
  910.     contWinPtr = TkpGetOtherWindow(macWin->toplevel->winPtr);
  911.     
  912.         if (contWinPtr != NULL) {
  913.             return TkMacGetDrawablePort((Drawable) contWinPtr->privatePtr);
  914.         } else {
  915.             panic("TkMacGetDrawablePort couldn't find container");
  916.             return NULL;
  917.         }    
  918.         
  919.     /*
  920.      * NOTE: Here we should handle out of process embedding.
  921.      */
  922.             
  923.     }
  924.  
  925. }
  926.  
  927. /*
  928.  *----------------------------------------------------------------------
  929.  *
  930.  * TkMacInvalClipRgns --
  931.  *
  932.  *    This function invalidates the clipping regions for a given
  933.  *    window and all of its children.  This function should be
  934.  *    called whenever changes are made to subwindows that would
  935.  *    effect the size or position of windows.
  936.  *
  937.  * Results:
  938.  *    None.
  939.  *
  940.  * Side effects:
  941.  *    The cliping regions for the window and its children are
  942.  *    mark invalid.  (Make sure they are valid before drawing.)
  943.  *
  944.  *----------------------------------------------------------------------
  945.  */
  946.  
  947. void
  948. TkMacInvalClipRgns(
  949.     TkWindow *winPtr)
  950. {
  951.     TkWindow *childPtr;
  952.     
  953.     /* 
  954.      * If already marked we can stop because all 
  955.      * decendants will also already be marked.
  956.      */
  957.     if (winPtr->privatePtr->flags & TK_CLIP_INVALID) {
  958.     return;
  959.     }
  960.     
  961.     winPtr->privatePtr->flags |= TK_CLIP_INVALID;
  962.     
  963.     /* 
  964.      * Invalidate clip regions for all children & 
  965.      * their decendants - unless the child is a toplevel.
  966.      */
  967.     childPtr = winPtr->childList;
  968.     while (childPtr != NULL) {
  969.     if (!Tk_IsTopLevel(childPtr) && Tk_IsMapped(childPtr)) {
  970.         TkMacInvalClipRgns(childPtr);
  971.     }
  972.     childPtr = childPtr->nextPtr;
  973.     }
  974.     
  975.     /*
  976.      * Also, if the window is a container, mark its embedded window
  977.      */
  978.      
  979.     if (Tk_IsContainer(winPtr)) {
  980.     childPtr = TkpGetOtherWindow(winPtr);
  981.  
  982.     if (childPtr != NULL && Tk_IsMapped(childPtr)) {
  983.         TkMacInvalClipRgns(childPtr);
  984.     }
  985.     
  986.     /*
  987.      * NOTE: Here we should handle out of process embedding.
  988.      */
  989.                 
  990.     }             
  991. }
  992.  
  993. /*
  994.  *----------------------------------------------------------------------
  995.  *
  996.  * TkMacWinBounds --
  997.  *
  998.  *    Given a Tk window this function determines the windows
  999.  *    bounds in relation to the Macintosh window's coordinate
  1000.  *    system.  This is also the same coordinate system as the
  1001.  *    Tk toplevel window in which this window is contained.
  1002.  *
  1003.  * Results:
  1004.  *    None.
  1005.  *
  1006.  * Side effects:
  1007.  *    None.
  1008.  *
  1009.  *----------------------------------------------------------------------
  1010.  */
  1011.  
  1012. void
  1013. TkMacWinBounds(
  1014.     TkWindow *winPtr,
  1015.     Rect *bounds)
  1016. {
  1017.     bounds->left = (short) winPtr->privatePtr->xOff;
  1018.     bounds->top = (short) winPtr->privatePtr->yOff;
  1019.     bounds->right = (short) (winPtr->privatePtr->xOff +
  1020.         winPtr->changes.width);
  1021.     bounds->bottom = (short) (winPtr->privatePtr->yOff +
  1022.         winPtr->changes.height);
  1023. }
  1024.  
  1025. /*
  1026.  *----------------------------------------------------------------------
  1027.  *
  1028.  * MacMoveWindow --
  1029.  *
  1030.  *    A replacement for the Macintosh MoveWindow function.  This
  1031.  *    function adjusts the inputs to MoveWindow to offset the root of 
  1032.  *    the window system.  This has the effect of making the coords 
  1033.  *    refer to the window dressing rather than the top of the content.
  1034.  *
  1035.  * Results:
  1036.  *    None.
  1037.  *
  1038.  * Side effects:
  1039.  *    Moves the Macintosh window.
  1040.  *
  1041.  *----------------------------------------------------------------------
  1042.  */
  1043.  
  1044. void 
  1045. MacMoveWindow(
  1046.     WindowRef window,
  1047.     int x,
  1048.     int y)
  1049. {
  1050.     int xOffset, yOffset;
  1051.  
  1052.     TkMacWindowOffset(window, &xOffset, &yOffset);
  1053.     MoveWindow((WindowRef) window, 
  1054.     (short) (x + xOffset), (short) (y + yOffset), false);
  1055. }
  1056.  
  1057. /*
  1058.  *----------------------------------------------------------------------
  1059.  *
  1060.  * UpdateOffsets --
  1061.  *
  1062.  *    Updates the X & Y offsets of the given TkWindow from the
  1063.  *    TopLevel it is a decendant of.
  1064.  *
  1065.  * Results:
  1066.  *    None.
  1067.  *
  1068.  * Side effects:
  1069.  *    The xOff & yOff fields for the Mac window datastructure
  1070.  *    is updated to the proper offset.
  1071.  *
  1072.  *----------------------------------------------------------------------
  1073.  */
  1074.  
  1075. static void
  1076. UpdateOffsets(
  1077.     TkWindow *winPtr,
  1078.     int deltaX,
  1079.     int deltaY)
  1080. {
  1081.     TkWindow *childPtr;
  1082.  
  1083.     if (winPtr->privatePtr == NULL) {
  1084.     /*
  1085.      * We havn't called Tk_MakeWindowExist for this window yet.  The
  1086.      * offset information will be postponed and calulated at that 
  1087.      * time.  (This will usually only happen when a mapped parent is
  1088.      * being moved but has child windows that have yet to be mapped.)
  1089.      */
  1090.     return;
  1091.     }
  1092.     
  1093.     winPtr->privatePtr->xOff += deltaX;
  1094.     winPtr->privatePtr->yOff += deltaY;
  1095.  
  1096.     childPtr = winPtr->childList;
  1097.     while (childPtr != NULL) {
  1098.     if (!Tk_IsTopLevel(childPtr)) {
  1099.         UpdateOffsets(childPtr, deltaX, deltaY);
  1100.     }
  1101.     childPtr = childPtr->nextPtr;
  1102.     }
  1103.     
  1104.     if (Tk_IsContainer(winPtr)) {
  1105.     childPtr = TkpGetOtherWindow(winPtr);
  1106.     if (childPtr != NULL) {
  1107.         UpdateOffsets(childPtr,deltaX,deltaY);
  1108.     }
  1109.         
  1110.     /*
  1111.      * NOTE: Here we should handle out of process embedding.
  1112.      */
  1113.             
  1114.     }
  1115. }
  1116.  
  1117. /*
  1118.  *----------------------------------------------------------------------
  1119.  *
  1120.  * Tk_GetPixmap --
  1121.  *
  1122.  *    Creates an in memory drawing surface.
  1123.  *
  1124.  * Results:
  1125.  *    Returns a handle to a new pixmap.
  1126.  *
  1127.  * Side effects:
  1128.  *    Allocates a new Macintosh GWorld.
  1129.  *
  1130.  *----------------------------------------------------------------------
  1131.  */
  1132.  
  1133. Pixmap
  1134. Tk_GetPixmap(
  1135.     Display *display,    /* Display for new pixmap (can be null). */
  1136.     Drawable d,        /* Drawable where pixmap will be used (ignored). */
  1137.     int width,        /* Dimensions of pixmap. */
  1138.     int height,
  1139.     int depth)        /* Bits per pixel for pixmap. */
  1140. {
  1141.     QDErr err;
  1142.     GWorldPtr gWorld;
  1143.     Rect bounds;
  1144.     MacDrawable *macPix;
  1145.     PixMapHandle pixels;
  1146.     
  1147.     if (display != NULL) {
  1148.     display->request++;
  1149.     }
  1150.     macPix = (MacDrawable *) ckalloc(sizeof(MacDrawable));
  1151.     macPix->winPtr = NULL;
  1152.     macPix->xOff = 0;
  1153.     macPix->yOff = 0;
  1154.     macPix->clipRgn = NULL;
  1155.     macPix->aboveClipRgn = NULL;
  1156.     macPix->referenceCount = 0;
  1157.     macPix->toplevel = NULL;
  1158.     macPix->flags = 0;
  1159.  
  1160.     bounds.top = bounds.left = 0;
  1161.     bounds.right = (short) width;
  1162.     bounds.bottom = (short) height;
  1163.     if (depth != 1) {
  1164.     depth = 0;
  1165.     }
  1166.  
  1167.     /*
  1168.      * Allocate memory for the off screen pixmap.  If we fail
  1169.      * try again from system memory.  Eventually, we may have
  1170.      * to panic.
  1171.      */
  1172.     err = NewGWorld(&gWorld, depth, &bounds, NULL, NULL, 0);
  1173.     if (err != noErr) {
  1174.     err = NewGWorld(&gWorld, depth, &bounds, NULL, NULL, useTempMem);
  1175.     }
  1176.     if (err != noErr) {
  1177.         panic("Out of memory: NewGWorld failed in Tk_GetPixmap");
  1178.     }
  1179.  
  1180.     /*
  1181.      * Lock down the pixels so they don't move out from under us.
  1182.      */
  1183.     pixels = GetGWorldPixMap(gWorld);
  1184.     LockPixels(pixels);
  1185.     macPix->portPtr = gWorld;
  1186.  
  1187.     return (Pixmap) macPix;
  1188. }
  1189.  
  1190. /*
  1191.  *----------------------------------------------------------------------
  1192.  *
  1193.  * Tk_FreePixmap --
  1194.  *
  1195.  *    Release the resources associated with a pixmap.
  1196.  *
  1197.  * Results:
  1198.  *    None.
  1199.  *
  1200.  * Side effects:
  1201.  *    Deletes the Macintosh GWorld created by Tk_GetPixmap.
  1202.  *
  1203.  *----------------------------------------------------------------------
  1204.  */
  1205.  
  1206. void 
  1207. Tk_FreePixmap(
  1208.     Display *display,        /* Display. */
  1209.     Pixmap pixmap)             /* Pixmap to destroy */
  1210. {
  1211.     MacDrawable *macPix = (MacDrawable *) pixmap;
  1212.     PixMapHandle pixels;
  1213.  
  1214.     display->request++;
  1215.     pixels = GetGWorldPixMap(macPix->portPtr);
  1216.     UnlockPixels(pixels);
  1217.     DisposeGWorld(macPix->portPtr);
  1218.     ckfree((char *) macPix);
  1219. }
  1220.  
  1221.